﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using arcchallenge.servicecontracts;

namespace arcchallenge.rot13
{
    public class Rot13Transformation : ILineTransformator
    {
        private const byte CAPITAL_LETTER_BASE = 65; // A
        private const byte SMALL_LETTER_BASE = 97; // a


        public void In_TransformLine(string line)
        {
            if (line != null)
            {
                var transformedBytes =
                    from b in Encoding.Default.GetBytes(line)
                    select Rot13Byte(b);

                this.Out_TransformedLine(new string(
                                             Encoding.Default.GetChars(
                                                 transformedBytes.ToArray())));
            }
            else
                this.Out_TransformedLine(null);
        }

        public event Action<string> Out_TransformedLine;


        internal static byte Rot13Byte(byte b)
        {
            if (IsCapitalLetter(b))
                return Rot13Byte(b, CAPITAL_LETTER_BASE);
            if (IsSmallLetter(b))
                return Rot13Byte(b, SMALL_LETTER_BASE);
            return b;
        }


        private static bool IsSmallLetter(byte b)
        {
            return IsKindOfLetter(b, SMALL_LETTER_BASE);
        }
        
        private static bool IsCapitalLetter(byte b)
        {
            return IsKindOfLetter(b, CAPITAL_LETTER_BASE);
        }

        private static bool IsKindOfLetter(byte b, byte letterBase)
        {
            return b >= letterBase && b <= (letterBase + 25);
        }


        private static byte Rot13Byte(byte b, byte letterBase)
        {
            return (byte)(letterBase + (((b - letterBase) + 13) % 26));
        }
    }
}
